package com.heima.wemedia.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.heima.common.constants.KafkaMessageConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.dtos.WmNewsDto;
import com.heima.model.common.dtos.WmNewsPageReqDto;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.entity.WmMaterial;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.model.wemedia.entity.WmNewsMaterial;
import com.heima.wemedia.dao.WmMaterialDao;
import com.heima.wemedia.dao.WmNewsDao;
import com.heima.wemedia.dao.WmNewsMaterialDao;
import com.heima.wemedia.service.WmNewsMaterialService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.util.WmThreadLocalUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 自媒体文章表(WmNews)表服务实现类
 *
 * @author makejava
 * @since 2022-04-12 16:03:07
 */
@Service("wmNewsService")
public class WmNewsServiceImpl implements WmNewsService {
    @Resource
    private WmNewsDao wmNewsDao;

    @Autowired
    private WmNewsMaterialService wmNewsMaterialService;
    @Autowired
    private WmMaterialDao wmMaterialDao;
    @Autowired
    private WmNewsMaterialDao wmNewsMaterialDao;

    @Autowired
    private KafkaTemplate kafkaTemplate;


    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public WmNews queryById(Long id) {
        return this.wmNewsDao.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param wmNews      筛选条件
     * @param pageRequest 分页对象
     * @return 查询结果
     */
    @Override
    public Page<WmNews> queryByPage(WmNews wmNews, PageRequest pageRequest) {
        long total = this.wmNewsDao.count(wmNews);
        return new PageImpl<>(this.wmNewsDao.queryAllByLimit(wmNews, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param wmNews 实例对象
     * @return 实例对象
     */
    @Override
    public WmNews insert(WmNews wmNews) {
        this.wmNewsDao.insert(wmNews);
        return wmNews;
    }

    /**
     * 修改数据
     *
     * @param wmNews 实例对象
     * @return 实例对象
     */
    @Override
    public WmNews update(WmNews wmNews) {
        this.wmNewsDao.update(wmNews);
        return this.queryById(wmNews.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.wmNewsDao.deleteById(id) > 0;
    }


    /*
    发布文章,修改文章,保存草稿
     */
    @Override
    public ResponseResult submit(WmNewsDto dto) {
        //参数校验
        if (StringUtils.isBlank(dto.getContent()) || StringUtils.isBlank(dto.getTitle())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //封装数据
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);// TODO: 2022/4/13 0013   status没有复制过去

        //抽取内容的中图片
        List<Map> contentList = JSON.parseArray(dto.getContent(), Map.class);

        List<String> contentImages = contentList.stream()
                .filter(map -> "image".equals(map.get("type")))
                .map(map -> map.get("value").toString())
                .collect(Collectors.toList());

        //抽取封面的图片
        List<String> images = dto.getImages();

        //自动的情况,封面图片需要从内容图片中获取
        if (dto.getType() == -1) {
            if (contentImages.size() >= 3) {
                images = contentImages.stream().limit(3).collect(Collectors.toList());
                wmNews.setType((short) 3);
            } else if (contentImages.size() > 0) {
                images = contentImages.stream().limit(1).collect(Collectors.toList());
                wmNews.setType((short) 1);
            } else {
                images = Collections.EMPTY_LIST;
            }
        }

        //封装封面图片
        if (!CollectionUtils.isEmpty(images)) {
            wmNews.setImages(StringUtils.join(images, ","));
        }

        // 3. 保存文章数据  新增  修改
        this.saveOrUpdateNews(wmNews);


        //4. 保存素材和文章的关联数据
        //4.1 保存文章和内容素材的引用关系
        saveContentImageRelation(contentImages, wmNews);

        //4.2保存文章和封面素材的引用关系
        saveCoverImageRelation(images, wmNews);


        //发送审核消息---------------------------------
        //发送消息通知审核服务进行文章审核 , 状态为 1 : 提交（待审核） 才需要审核
        if (wmNews.getStatus() == 1) {
            kafkaTemplate.send(KafkaMessageConstants.WM_NEWS_AUTO_SCAN_TOPIC, wmNews.getId().toString());
        }

        return ResponseResult.okResult("文章发布成功");
    }


    /*
    分页查询文章列表
     */
    @Override
    public ResponseResult list(WmNewsPageReqDto dto) {
        //参数校验
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();


        Map<String, Object> queryParam = BeanUtil.beanToMap(dto);

        queryParam.put("userId",WmThreadLocalUtil.get().getId());
        PageHelper.startPage(dto.getPage(),dto.getSize());

        //封装查询条件
        com.github.pagehelper.Page<WmNews> page = wmNewsDao.queryByMap(queryParam);

        //封装数据返回
        PageResponseResult result = new PageResponseResult(dto.getPage(),dto.getSize(), (int) page.getTotal());
        result.setData(page.getResult());


        return result;
    }

    @Override
    public ResponseResult del(Long id) {
        WmNews wmNews = wmNewsDao.queryById(id);
        if(wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if (wmNews.getStatus()==9){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        wmNewsDao.deleteById(id);

        return ResponseResult.okResult("删除文章成功");
    }

    private void saveCoverImageRelation(List<String> images, WmNews wmNews) {
        if (CollectionUtils.isEmpty(images)) {
            return;
        }
        saveImageRelation(images, wmNews, 0);
    }


    private void saveContentImageRelation(List<String> contentImages, WmNews wmNews) {

        if (CollectionUtils.isEmpty(contentImages)) {
            return;
        }
        saveImageRelation(contentImages, wmNews, 1);
    }

    /*
    保存文章与素材关联关系
     */
    private void saveImageRelation(List<String> contentImages, WmNews wmNews, int i) {

        if (wmNews.getStatus() == 0) {
            return;
        }
        WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
        //给图片去重
        contentImages = contentImages.stream().distinct().collect(Collectors.toList());
        List<WmMaterial> list = wmMaterialDao.queryByUrl(contentImages);
        //提取素材id
        List<Long> ids = list.stream().map(wmMaterial -> wmMaterial.getId()).collect(Collectors.toList());
        //判断是否有缺失 情景,文章引用图片未发表时,素材被删除
        if (contentImages.size() > ids.size()) {
            throw new RuntimeException("素材数据缺失");
        }
        //public int saveImageRelation(@Param("newsId") Long newsId,@Param("materialIds") List<Long> materialIds, @Param("type") short type);
        wmNewsMaterialDao.saveImageRelation(wmNews.getId(), ids, (short) 0);
    }


    /*
    保存和修改文章
     */
    private void saveOrUpdateNews(WmNews wmNews) {
        wmNews.setUserId(WmThreadLocalUtil.get().getId());
        wmNews.setCreatedTime(new Date());
        wmNews.setEnable(1);

        //如果id为空代表新增,
        if (wmNews.getId() == null) {
            wmNewsDao.insert(wmNews);
        }

        //更新文章
        wmNewsDao.update(wmNews);
        //删除文章与素材关联表数据
        wmNewsMaterialService.deleteByNewsId(wmNews.getId());
    }
}
